/**消息对象，全局控制消息显示方式
 * @author yenbay
 * @description 通用的消息对象，包括弹窗，提示框等等
 * @version 2017.05.05
 * @example
 * //javascript
   messager.pop(this.value,this,false,"right top");
   messager.pop(this.value,this);
   messager.confirm("是不是",function(accept){
        if(accept){
            alert("ok");
        }else{
            alert("not ok");
        }
    });  
    messager.alert(this.value); 
    messager.prompt("请输入你的生日",function(value){
        alert(value);
    },"1997-01-02"); 
    messager.info(this.value,true,function(){
         
    }); 
    messager.success(this.value, 6000);
    messager.warning(this.value);
    messager.error(this.value,null,function(){
        setTimeout(function(){
            alert(document.body.outerHTML);
        },15000);
    });
    messager.show((new Date().getTime()),false,function(){

    }); 
    messager.show((new Date().getTime()));
    messager.tips(this.value);
   //返回对象具有close方法，例如 var obj=messager.pop(ddd,document.body,true);obj.close();//关闭
 * //---end ---example
 */
var messager = (function(){
    return {  
    alert:function(msg,callback){
        //【alert功能】弹出警告框 
        var me=this,id="_messager_alert",_window=self==top?self:top,message=me._window_common(id,msg,"alert");
        if(!message) return;
        var dialog= message.childNodes[0].childNodes[0]; 
        //按钮组
        var buttons=me.create(_window,"p"); 
        buttons.style.textAlign="right";
        var ok=me.create(_window,"span","messager-window-button",null,null,"确定");//确定按钮
        me.addEvent(ok,"click",function(){ 
            me.remove(this.parentNode.parentNode.parentNode.parentNode); 
            if(callback && typeof callback == "function") callback(true);
        });//按钮事件 
        me.addEvent(ok,"mouseover",function(evt){ //按钮滑动
            this.className=this.className+" messager-window-button-hover";
        }); 
        me.addEvent(ok,"mouseout",function(evt){//按钮滑出
            this.className=this.className.replace("messager-window-button-hover","").trim();
        });
        buttons.appendChild(ok);
        dialog.appendChild(buttons); 
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        };
    },
    confirm:function(msg,callback){
        //【confirm功能】弹出确认框 
        if(!close){
            if(!callback) throw new Error("messager.confirm(msg,callback) 缺少参数,两个参数，请参考使用帮助！"); 
            if(typeof callback!= "function") throw new Error("messager.confirm(msg,callback) 第二个参数必须为回掉函数,请参考使用帮助!");
        } 
        var me=this, id="_messager_confirm",_window=self==top?self:top,message=me._window_common(id,msg,"confirm");
        if(!message) return false; 
        var dialog= message.childNodes[0].childNodes[0];
         //按钮组
        var buttons=me.create(_window,"p");
        buttons.style.textAlign="right";
        //确认 
        var ok=me.create(_window,"span","messager-window-button",null,null,"确定");//确定按钮
        me.addEvent(ok,"click",function(evt){
            //确定 
            me.remove(this.parentNode.parentNode.parentNode.parentNode); 
            if(callback && typeof callback == "function") callback(true); 
        });  
        me.addEvent(ok,"mouseover",function(evt){ //按钮滑动
            this.className=this.className+" messager-window-button-hover";
        }); 
        me.addEvent(ok,"mouseout",function(evt){//按钮滑出
            this.className=this.className.replace("messager-window-button-hover","").trim();
        }); 
        buttons.appendChild(ok); 
        //取消
        var cancel=me.create(_window,"span","messager-window-button",null,null,"取消");//确定按钮
        me.addEvent(cancel,"click",function(evt){
            //取消 
            me.confirm(null,null,true);
            if(callback && typeof callback == "function") callback(false); 
        }); 
         me.addEvent(cancel,"mouseover",function(evt){ //按钮滑动
            this.className=this.className+" messager-window-button-hover";
        }); 
        me.addEvent(cancel,"mouseout",function(evt){//按钮滑出
            this.className=this.className.replace("messager-window-button-hover","").trim();
        }); 
        buttons.appendChild(cancel);
        dialog.appendChild(buttons); 
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        };
    },
    prompt:function(msg,callback,defaultValue){
        //【prompt功能】弹出提示输入内容框
        if(!close){
            if(!callback) throw new Error("messager.prompt(msg,callback,defaultValue) 缺少参数,至少两个参数，请参考使用帮助！"); 
            if(typeof callback!= "function") throw new Error("messager.prompt(msg,callback,defaultValue) 第二个参数必须为回掉函数,请参考使用帮助!");
        } 
        var me=this, id="_messager_prompt",_window=self==top?self:top,message=me._window_common(id,msg,"prompt");
        if(!message) return false; 
        var dialog= message.childNodes[0].childNodes[0];
        //输入框
        var input=me.create(_window,"input","messager-window-prompt-input",null,"_window_prompt_input");
        input.type="text";
        input.value=defaultValue;
        dialog.appendChild(input);
        //按钮组
        var buttons=me.create(_window,"p");
        buttons.style.textAlign="right";
        //确认 
        var ok=me.create(_window,"span","messager-window-button",null,null,"确定");//确定按钮
        me.addEvent(ok,"click",function(evt){
            //确定 
            me.remove(this.parentNode.parentNode.parentNode.parentNode);
            var _value = input.value;  
            input.value = ""; 
            if(callback && typeof callback == "function") callback(_value); 
        });  
        me.addEvent(ok,"mouseover",function(evt){ //按钮滑动
            this.className=this.className+" messager-window-button-hover";
        }); 
        me.addEvent(ok,"mouseout",function(evt){//按钮滑出
            this.className=this.className.replace("messager-window-button-hover","").trim();
        }); 
        buttons.appendChild(ok); 
        //取消
        var cancel=me.create(_window,"span","messager-window-button",null,null,"取消");//确定按钮
        me.addEvent(cancel,"click",function(evt){
            //取消 
            me.remove(this.parentNode.parentNode.parentNode.parentNode);
            if(callback && typeof callback == "function") callback(false); 
        }); 
        me.addEvent(cancel,"mouseover",function(evt){ //按钮滑动
            this.className=this.className+" messager-window-button-hover";
        }); 
        me.addEvent(cancel,"mouseout",function(evt){//按钮滑出
            this.className=this.className.replace("messager-window-button-hover","").trim();
        }); 
        buttons.appendChild(cancel);
        dialog.appendChild(buttons);  
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        };
    }, 
    //弹出对话框基础部分
    _window_common:function(id,msg,type){
        var me=this,_window=self==top?self:top;
        msg = me.msgFilter(msg);
        var oldmessage=_window.document.getElementById(id);
        if(oldmessage){
            me.remove(oldmessage);
        } 
        //消息控件
        var message=me.create(_window,"div","messager-window-default",id);
        //标题
        var title=me.create(_window,"div","messager-window-dialog-title",null,null,"<p><span>提示</span></p>"); 
        //内容
        var text=me.create(_window,"div","messager-window-dialog-content",null,null,"<p>"+msg+"</p>"); 
        //内容容器
        var box=me.create(_window,"div","messager-window-dialog-box");  
        box.appendChild(text); 
         //窗口
        var dialog=me.create(_window,"div","messager-window-dialog"); 
        dialog.appendChild(title);
        dialog.appendChild(box);
        //掩层 
        var mask=me.create(_window,"div","messager-window-mask"); 
        //关闭点击事件
        me.addEvent(mask,"click",function(evt){ 
            evt.preventDefault?evt.preventDefault():(evt.returnValue = false); 
            if(evt.stopPropagation) evt.stopPropagation();
            return false;
        }); 
        //关闭右键菜单
        me.addEvent(mask,"contextmenu",function(evt){
            evt.preventDefault?evt.preventDefault():(evt.returnValue = false); 
            if(evt.stopPropagation) evt.stopPropagation();
            return false;
        });   
        mask.appendChild(dialog);   
        message.appendChild(mask);
        _window.document.body.appendChild(message);
        message.style.zIndex=me.getMaxZIndex(_window)+1;  
        //调整尺寸
        function resize(_window,mask,dialog){
                var winSize=me.getWindowSize(_window);
                mask.style.width=winSize.w+"px";
                mask.style.height=winSize.h+"px";
                //调整dialog窗口高度，居于中间        
                var _margin_top=(winSize.h-dialog.offsetHeight)/2;
                if(_margin_top>35) _margin_top  = _margin_top -35;//35px是浏览器头的一般高度
                dialog.style.marginTop=_margin_top+"px";  
        }
        //重置尺寸
        resize(_window,mask,dialog); 
        me.addEvent(_window,"resize",function(){
             resize(_window,mask,dialog);
        }); 
        return message;
    },
    show:function(msg,timeout,callback){
        //【easyui的$.messager.show功能】右下角弹出消息
        var me=this, _window=self==top?self:top;
        msg = me.msgFilter(msg);
        message=me.create(_window,"div","messager-show-default"); 
        message.style.position="fixed";
        message.style.bottom="-600px"; 
        message.style.right="0px"; 
        message.style.zIndex=me.getMaxZIndex(_window)+1;
        //消息标题
        var title=me.create(_window,"p"); 
        title.style.textAlign="left"; 
        title.innerHTML = "<span style=\"font-weight:bold;\">消息:</span>";
        var cross=me.create(_window,"span","messager-show-close",null,null,"X"); 
        title.appendChild(cross);
        message.appendChild(title);
        //消息内容
        var text=me.create(_window,"div","messager-show-content");
        text.innerHTML= "<p>"+ msg +"</p>";
        message.appendChild(text);
        _window.document.body.appendChild(message); 
        //监听关闭
        me.addEvent(cross,"click",function(evt){
            var object=this.parentNode.parentNode;
            me.animate(object,"bottom","-600px",function(){ 
                 me.remove(object);
            });  
        }); 
        me.addEvent(cross,"mouseover",function(evt){
            this.className = this.className+" messager-show-close-hover"; 
        }); 
        me.addEvent(cross,"mouseout",function(evt){
            this.className = this.className.replace("messager-show-close-hover","").trim();
        });  
        //滑出
        me.animate(message,"bottom","0px",function(){
            var _message=this;
            if(callback && typeof callback == "function") callback();
              //设置超时 
            if(timeout!=false) setTimeout(function(){   
                me.animate(_message,"bottom","-600px",function(){
                    me.remove(_message);
                }); 
            }, 3000);
        },20);  
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        }; 
    },
    tips:function(msg,timeout,callback){
        //【easyui的$.messager.show功能，位置移到顶部中间】窗口顶部中间弹出消息
        var me=this, _window=self==top?self:top;
        msg = me.msgFilter(msg);
        message=me.create(_window,"div","messager-tips-default"); 
        message.style.position="fixed";
        message.style.top="-600px";  
        message.style.zIndex=me.getMaxZIndex(_window)+1;
        //消息标题
        var title=me.create(_window,"p"); 
        title.style.textAlign="left"; 
        title.innerHTML = "<span style=\"font-weight:bold;\">消息:</span>";
        var cross=me.create(_window,"span","messager-tips-close",null,null,"X"); 
        title.appendChild(cross);
        message.appendChild(title);
        //消息内容
        var text=me.create(_window,"div","messager-tips-content");
        text.innerHTML= "<p>"+msg+"</p>";
        message.appendChild(text);
        _window.document.body.appendChild(message); 
        message.style.left=(me.getWindowSize(_window).w/2-message.offsetWidth/2)+"px";
        //监听关闭
        me.addEvent(cross,"click",function(evt){
            var object=this.parentNode.parentNode;
            me.animate(object,"top","-600px",function(){ 
                 me.remove(object);
            });  
        }); 
        me.addEvent(cross,"mouseover",function(evt){
            this.className = this.className+" messager-tips-close-hover"; 
        }); 
        me.addEvent(cross,"mouseout",function(evt){
            this.className = this.className.replace("messager-tips-close-hover","").trim();
        });  
        //滑出
        me.animate(message,"top","0px",function(){
            var _message=this;
            if(callback && typeof callback == "function") callback();
              //设置超时 
            if(timeout!=false) setTimeout(function(){   
                me.animate(_message,"top","-600px",function(){
                    me.remove(_message);
                }); 
            }, 3000);
        },20);  
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        }; 
    }, 
    msgFilter: function(msg){
        var _msg = msg;
        if(msg && /[<]/.test(msg)){
           var exTag="p|div|body|table|html|script|link|style|table|td|tr|head|iframe|ul|li"; 
            _msg = _msg.replace(new RegExp("<("+exTag+")[^>]*\\/{0,1}>|</("+exTag+")>","gi"),"");  
        } 
        return _msg || "";
    },
    success:function(msg,timeout,callback){
        //【bootstrap的message-alert的success功能】顶部弹出成功消息，可关闭，自动关闭
        var me=this, message=null;  
        return me._topMsg_common(message,"成功",msg,"success",timeout,callback); 
    },
    info: function(msg,timeout,callback){
        //【bootstrap的message-alert的info功能】顶部弹出消息，可关闭，自动关闭 
        var me=this, message=null;  
        return me._topMsg_common(message,"消息",msg,"info",timeout,callback); 
    },
    warning:function(msg,timeout,callback){
        //【bootstrap的message-alert的warn功能】顶部弹出警告消息，可关闭，自动关闭
        var me=this, message=null;  
        return me._topMsg_common(message,"警告",msg,"warning",timeout,callback); 
    },
    error:function(msg,timeout,callback){
        //【bootstrap的message-alert的danger功能】顶部弹出错误消息，可关闭，默认不会自动关闭
        var me=this, message=null;  
        return me._topMsg_common(message,"错误",msg,"error",timeout,callback); 
    },
    //顶部消息模块公共部分
    _topMsg_common:function(message,title,msg,type,timeout,callback){
        var me=this, _window=self==top?self:top;
        msg = me.msgFilter(msg);
        message=me.create(_window,"div","messager-top-message"); 
        message.style.position="fixed";
        message.style.top="-600px";  
        message.style.zIndex=me.getMaxZIndex(_window)+1;
        var box=me.create(_window,"div"); 
        var content=me.create(_window,"p"); 
        content.innerHTML = "<span>"+title+"</span>&nbsp;!&nbsp;"+msg;
        var cross=me.create(_window,"span","messager-top-message-close",null,null,"X"); 
        content.appendChild(cross);
        box.appendChild(content);
        message.appendChild(box);
        _window.document.body.appendChild(message);
        me.addEvent(cross,"click",function(evt){
            var object=this.parentNode.parentNode.parentNode;
            me.animate(object,"top","-600px",function(){
                me.remove(object);
            }); 
            evt.preventDefault?evt.preventDefault():(evt.returnValue = false); 
            if(evt.stopPropagation) evt.stopPropagation();
            return false;
        });
        me.addEvent(message,"click",function(evt){
            me.remove(this);
            evt.preventDefault?evt.preventDefault():(evt.returnValue = false); 
            if(evt.stopPropagation) evt.stopPropagation();
            return false;
        }); 
        message.className = message.className+" messager-top-message-"+type;
        me.addEvent(message,"mouseover",function(evt){
            this.className = this.className +" messager-top-message-"+type+"-hover";
        });
        me.addEvent(message,"mouseout",function(evt){
            this.className = this.className.replace("messager-top-message-"+type+"-hover","").trim();
        });   
        //居中
        message.style.left = (me.getWindowSize(_window).w/2-message.offsetWidth/2)+"px";
        //滑出
        me.animate(message,"top","0px",function(){
            var _message = this;
            if(callback && typeof callback == "function") callback();
            if(timeout!=false) setTimeout(function(){
            me.animate(_message,"top","-600px",function(){
                me.remove(_message);
            }); 
            },(timeout && !isNaN(timeout+"")) ? timeout : 3000); 
        },20); 
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        };
    },
    pop:function(msg,element,timeout,relpos,offset){ 
        //清理旧的
        var me=this,id="_messager_pop"; 
        var oldmessage=document.getElementById(id);
        if(oldmessage) me.remove(oldmessage);
        msg = me.msgFilter(msg);
         //元素上/下/左/右弹出
        var pos=me.getPosition(element); 
        if(offset){
            //偏移量
            pos.x=pos.x+offset.x;//245
            pos.y=pos.y+offset.y;//145
        } 
        var message=me.create(window,"div","messager-pop-default",id); 
        document.body.appendChild(message);
        //消息内容
        var text=me.create(window,"p",null,null,null,msg);
        message.appendChild(text); 
        me.addEvent(text,"click",function(){
            me.remove(this.parentNode);
        }); 
        //定位 
        message.style.position="fixed";  
        message.style.left = (pos.x+pos.w)+"px";
        message.style.top = (pos.y)+"px"; 
        if(relpos) relpos.replace(/(\w+)[\W]+(\w+)/gi,function(s0,s1,s2){
            var h=s1.toLowerCase(),v=s2 && s2.toLowerCase();//h水平，v垂直  
            var _position = h+" "+v;  
            switch(_position){
                case "left top": 
                    message.style.left=pos.x+"px";
                    message.style.top=(pos.y-message.offsetHeight)+"px";
                    break;   
                case "left bottom":
                    message.style.left=pos.x+"px";
                    message.style.top=(pos.y+pos.h)+"px";
                    break;
                case "right top":
                    message.style.left=(pos.x+pos.w)+"px";
                    message.style.top=pos.y+"px";
                    break;
                case "right bottom":  
                    message.style.left=(pos.x+pos.w-message.offsetWidth)+"px";
                    message.style.top=(pos.y+pos.h)+"px";
                    break; 
                default:break;
            } 
        }); 
        //定时删除 
        if(timeout!=false) setTimeout(function(){
              me.remove(message);
        }, timeout && !isNaN(timeout+"") ? timeout : 1000); 
        return {
        	element:message,
        	close:function(){
        		me.remove(this.element);
        	}
        };
    },  
    //添加元素
    create:function(_window,tagName,className,id,name,innerHtml){
        var ele=_window.document.createElement(tagName);
        if(id){ if(ele.id){ ele.id=id; }else ele.setAttribute("id",id); }
        if(name){ if(ele.name){ ele.name=name; }else ele.setAttribute("name",name); }
        if(id){ if(ele.id){ ele.id=id; }else ele.setAttribute("id",id); }
        if(className) ele.className=className;
        if(innerHtml) ele.innerHTML=innerHtml;
        return ele;
    },
    //删除元素
    remove: function(element){ 
        try{ 
            var _pNode=element && element.parentNode;
            if(_pNode) _pNode.removeChild(element); 
            return true;
        }catch(e){ 
            console.error(e);
        }
        return false; 
    },
    //获取窗口大小
    getWindowSize:function(_window){
        var winWidth = 0, winHeight = 0;
        //获取窗口宽度 
        if (_window.innerWidth) winWidth = _window.innerWidth; 
        else if ((_window.document.body) && (_window.document.body.clientWidth)) winWidth = _window.document.body.clientWidth; 
        // 获取窗口高度 
        if (_window.innerHeight) winHeight = _window.innerHeight; 
        else if ((_window.document.body) && (_window.document.body.clientHeight)) winHeight = _window.document.body.clientHeight; 
        return {"w":winWidth,"h":winHeight};
    },
    //获取元素位置左定点位置x,y，及元素盒子宽度，高度
    getPosition: function(element) { 
        var top = document.documentElement.clientTop,
        left = document.documentElement.clientLeft,
        rect = element.getBoundingClientRect();  
            return {
            y: rect.top - top, 
            x: rect.left - left,
            w: element.offsetWidth,
            h: element.offsetHeight
        };
    },
    //返回最大的z-index
    getMaxZIndex:function(_window){ 
        var zIndexMax=0; 
        var all = _window.document.all;
        for(var k=0;k<all.length;k++){ 
            var zIndex=all[k].style.zIndex; 
            zIndexMax=zIndex&&zIndex>zIndexMax?zIndex:zIndexMax;
        } 
        return zIndexMax;
    },
    //添加事件
    addEvent:function(element,event,handleFun){ 
        if(element.addEventListener){ element.addEventListener(event,handleFun,false); } 
        else if(element.attachEvent){ element.attachEvent("on"+event,handleFun); }
        else{ element["on"+event] = handleFun; } 
    },
    //移除事件
    removeEvent:function(element,event,handleFun){ 
        if (element.removeEventListener){ element.removeEventListener(event,handleFun,false); }
        else if (element.detachEvent) { element.detachEvent("on"+event,handleFun); }
        else {element["on"+event] = null; } 
    },
    animate:function(dom,attr,target,callback,step){
        try{
        var me=this,_step = step && !isNaN(step) ? step: 25;
        _step = _step > 25 ? 25: _step;
        if(!target) throw new Error("target cannot be null or undefined!");
        var _target = !isNaN(target)? target : parseInt(target.toString().replace(/\d+/,"$&"));
        clearInterval(dom.timer);
        if(dom && /\[object\shtml\S*element\]/gi.test(Object.prototype.toString.call(dom))) 
            dom.timer = setInterval(function(){  
              var cur = 0;
              if(attr == "opacity"){
                  cur = Math.round(parseFloat(me.getStyle(dom,attr).replace(/\d+/,"$&"))*100);
                }else{
                  cur = parseInt(me.getStyle(dom,attr).replace(/\d+/,"$&"));
                } 
              //速度
              var speed = (_target-cur)/8;
              speed = speed>0?Math.ceil(speed):Math.floor(speed); 
                if(cur == _target){
                    clearInterval(dom.timer);
                    if(typeof callback == "function"){
                      callback(dom);
                    }
                }else if(/\[object\shtml\S*element\]/gi.test(Object.prototype.toString.call(dom))){
                  if(attr == "opacity"){
                        dom.style.filter = "alpha(opacity="+(cur+speed)+")";
                        dom.style.opacity = (cur+speed)/100;
                    }else{
                        dom.style[attr] = cur + speed + "px";
                    }
                }else clearInterval(dom.timer);
            },_step); 
        }catch(e){
            console.error(e.message);
            clearInterval(dom.timer);
        }
    },
    getStyle: function(element,name){
        if(/\[object\shtml\S*element\]/gi.test(Object.prototype.toString.call(element))){
            if(element.currentStyle){
              return element.currentStyle[name];
            }else{
              return getComputedStyle(element,false)[name];
            }
        }
        return ""; 
    }
}; 
})();